namespace Bootsy.Skype

import System
import System.Threading
import SKYPE4COMLib as Skype4COM
import Bootsy.Core
import ConcurrentBoo.Executors

class SkypeChatService(IChatService):
	
	_executor = MessageLoopExecutor()
	_participants = array(IChatParticipant, 0)
	_skype as Skype4COM.SkypeClass
	
	Participants:
		[lock]
		get:
			return _participants
			
	[lock]
	def RegisterParticipant([required] participant as IChatParticipant):
		_participants += (participant,)
		
	def Start():
		_skype = Skype4COM.SkypeClass()
		_skype.MessageStatus += OnMessage
		_skype.Attach(5, false)
			
	private def OnMessage(message as Skype4COM.IChatMessage, status):
		if message.Type != Skype4COM.TChatMessageType.cmeSaid: return
		if message.Status not in (
					Skype4COM.TChatMessageStatus.cmsReceived,
					Skype4COM.TChatMessageStatus.cmsSent):
			return
		
		Dispatch(message)
			
	private def Dispatch(message as Skype4COM.IChatMessage):
		messageAdaptor = ChatMessageAdapter(message)
		for participant in self.Participants:
			ConcurrentBoo.queueUserWorkItem() do:
				try:
					participant.OnMessage(messageAdaptor)
				except x:
					OnError(x)
				
	private def OnError(x as Exception):
		Console.Error.WriteLine(x)
		
	class ChatUserAdapter(IChatUser):
		
		_user as Skype4COM.IUser
		
		def constructor(user as Skype4COM.IUser):
			_user = user
			
		FullName:
			get:
				return _user.FullName
				
	class ChatMessageAdapter(IChatMessage, IChat):
		
		_message as Skype4COM.IChatMessage
		_sender as IChatUser
		
		def constructor(message as Skype4COM.IChatMessage):
			_message = message
			
		Body:
			get:
				return _message.Body
				
		Chat:
			get:
				return self
				
		Sender:
			[lock]
			get:
				if _sender is null:
					_sender = ChatUserAdapter(_message.Sender)
				return _sender
				
		def PostMessage(body as string):
			_message.Chat.SendMessage(body)

				
